package com.google.code.coma.rmi;

import com.google.code.coma.rmi.storage.StorageService;
import com.google.code.coma.rmi.storage.StorageServiceImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Dominik Strasser, dominikstr@gmail.com
 */
public class RMIManager {
	private static final Log log = LogFactory.getLog(RMIManager.class);

	private static final String RMI_HOST = "localhost";

	private static final int RMI_PORT = 10099;

	private static List<StorageService> exportedServices = new ArrayList<StorageService>();

	public static StorageService getStorageService(String storageName) {
		try {
			Registry registry = LocateRegistry.getRegistry(RMI_HOST, RMI_PORT);
			try {
				StorageService service = (StorageService) registry.lookup(storageName);
				if (service != null)
					return service;
			} catch (NotBoundException e) {
				StorageService service = new StorageServiceImpl();
				Remote obj = UnicastRemoteObject.exportObject(service, 0);
				registry.bind(storageName, obj);
				exportedServices.add(service);
				return (StorageService) registry.lookup(storageName);
			}
		} catch (Exception e) {
			log.info("storage service not found");
		}
		try {
			StorageService service = new StorageServiceImpl();
			Remote obj = UnicastRemoteObject.exportObject(service, 0);
			Registry registry = LocateRegistry.createRegistry(RMI_PORT);
			registry.bind(storageName, obj);
			exportedServices.add(service);
			if (log.isInfoEnabled()) {
				log.info("Bound storage service " + storageName);
			}
			return (StorageService) registry.lookup(storageName);
		} catch (Exception e1) {
			log.error("Unable to export object", e1);
			throw new RuntimeException(e1);
		}
	}
}
